package com.binguo.transfer;

import com.binguo.common.enums.CardType;
import com.binguo.common.enums.PayType;
import com.binguo.common.util.CommonUtil;
import com.binguo.model.api.vo.OrderItemVO;
import com.binguo.model.api.vo.OrderVO;
import com.binguo.model.api.vo.OrderVOInWX;
import com.binguo.model.model.*;
import com.binguo.model.repository.CaogenyaoPaycardRepository;
import com.binguo.model.repository.CustomerRepository;
import com.binguo.model.repository.OrderItemRepository;
import com.binguo.model.wxapi.vo.CaoGenYaoPayCardVO;
import com.binguo.service.CustomerService;
import com.binguo.service.PayService;
import com.binguo.service.ShopService;
import com.binguo.thirdPay.caoGenYaoPay.CaoGenYaoPay;
import com.binguo.thirdPay.hzShiMing.HZShiMingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tk.mybatis.mapper.entity.Condition;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created by haibang on 18/5/15.
 */
@Component
public class OrderVOTransfer {
    @Autowired
    OrderItemRepository orderItemRepository;

    @Autowired
    ShopService shopService;

    @Autowired
    PayService payService;

    @Autowired
    HZShiMingService hzShiMingService;

    @Autowired
    CustomerRepository customerRepository;

    @Autowired
    CustomerService customerService;

    @Autowired
    CaogenyaoPaycardRepository caogenyaoPaycardRepository;

    @Resource
    CaoGenYaoPay caoGenYaoPay;

    public OrderVO toOrderVO(BinguoOrder order){

        Integer SMKOrderType = 5;

        List<OrderItemVO> orderItems = getOrderItemListByOrderNo(order.getOrderno());
        String shopName = shopService.findShopNameById(order.getShopid());

        PayCard payCard;

        System.out.println("----------");
        System.out.println(order.getCardno());
        System.out.println("----------");

        if (order.getCardno() == null || "".equals(order.getCardno())){
            payCard = null;
        } else {
            payCard = null;
            if (order.getCustomerid() != null) {
                List<PayCard> payCardList = payService.getPayCardByCustomerAndShop(order.getCustomerid(), order.getShopid());
//                List<PayCard> payCardList = payService.getPayCardByCustomerId(order.getCustomerid(), order.getSource());

                if (payCardList != null && payCardList.size() > 0) {
                    Long accountBalance = 0L;
                    for (PayCard temp : payCardList) {
                        accountBalance += temp.getAccountbalance() + temp.getWxAccountbalance() + temp.getYktAccountbalance() + temp.getBzAccountbalance();

                        //来源，0：二维码支付，1：人脸支付，2：实体卡支付，3：其他支付，4:被扫支付

                        if (temp.getId().equals(order.getCardid())) {
                            payCard = temp;
                        }else {
                            if (order.getSource().intValue() == 1 && temp.getCardtype() == CardType.BINGUO_CARD.getCode().byteValue()) {
                                payCard = temp;
                            }else {
                                if (order.getOrdertype().equals(SMKOrderType) && order.getSource().intValue() == 2) {
                                    payCard = temp;
                                }
                            }

                        }

                    }
                    if (payCard != null) {
                        payCard.setAccountbalance(accountBalance);
                    }
                }
            }
        }
        String SMKAccountBalance = null;
        if (order.getOrdertype().equals(SMKOrderType)){
            Customer customer = customerRepository.findById(order.getCustomerid());
            SMKAccountBalance  = customerService.getSMKAcountBalance(customer);
            if (SMKAccountBalance == null){
                SMKAccountBalance = "";
            }
            order.setRealfee(order.getYktMoney());
        }

        int result = order.getOrderno().indexOf("CGY");
        if(result != -1){
            Long cardId;
            ShopCaogenyaoConfig config = shopService.getCaoGenYaoConfig(order.getShopid());
            if (order.getSource().equals(PayType.FACEPAY.getCode().byteValue())) {
                Condition cardCondition = new Condition(CaogenyaoPaycard.class);
                cardCondition.or().andEqualTo("customerid", order.getCustomerid());
                List<CaogenyaoPaycard> caogenyaoPaycardList = caogenyaoPaycardRepository.findByCondition(cardCondition);
                CaogenyaoPaycard caogenyaoPaycard = caogenyaoPaycardList.get(0);
                cardId = caogenyaoPaycard.getCardid();
            }else {
                List<CaoGenYaoPayCardVO> cardList = caoGenYaoPay.findCardNoByValue(order.getCardno(),config.getCgyCompanyId(),null,config.getCgyShopId(),1);
                CaoGenYaoPayCardVO cardVO = cardList.get(0);
                cardId = Long.parseLong(cardVO.getCardId());
                payCard = new PayCard();
                payCard.setCardno(order.getCardno());
            }
            Long caoGenYaoBalance = caoGenYaoPay.findBalanceByCardId(cardId,config.getCgyCompanyId().longValue());
            payCard.setAccountbalance(caoGenYaoBalance);
        }

        return OrderVO.builder()
                .id(order.getId())
                .orderNo(order.getOrderno())
                .serialNumber(order.getSerialnumber())
                .shopId(order.getShopid())
                .serial(CommonUtil.getSerial(order.getSerial()))
                .shopName(shopName)
                .cashierDeskId(order.getCashierdeskid())
                .customerId(order.getCustomerid())
                .customerName(order.getCustomername())
                .customerPhone(order.getCustomerphone())
                .payType(order.getSource())
                .totalFee(order.getTotalfee())
                .realFee(order.getRealfee())
                .refundFee(order.getRefundfee())
                .payStatus(order.getPaystatus())
                .refundStatus(order.getRefundstatus())
                .note(order.getNote())
                .payTime(order.getPaytime().getTime())
                .refundTime(order.getRefundtime().getTime())
                .itemCount(order.getTotalquantity())
                .orderItems(orderItems)
                .payCard(payCard)
                .productOrderUrl(order.getProductOrderUrl())
                .SMKAccountBalance(SMKAccountBalance)
                .build();
    }

    public OrderVO toOrderVOWithBalance(BinguoOrder order,
                                        Long balance){
        List<OrderItemVO> orderItems = getOrderItemListByOrderNo(order.getOrderno());
        String shopName = shopService.findShopNameById(order.getShopid());

        PayCard payCard = new PayCard();
        payCard.setAccountbalance(balance);

        return OrderVO.builder()
                .id(order.getId())
                .orderNo(order.getOrderno())
                .serialNumber(order.getSerialnumber())
                .shopId(order.getShopid())
                .serial(CommonUtil.getSerial(order.getSerial()))
                .shopName(shopName)
                .cashierDeskId(order.getCashierdeskid())
                .customerId(order.getCustomerid())
                .customerName(order.getCustomername())
                .customerPhone(order.getCustomerphone())
                .payType(order.getSource())
                .totalFee(order.getTotalfee())
                .realFee(order.getRealfee())
                .refundFee(order.getRefundfee())
                .payStatus(order.getPaystatus())
                .refundStatus(order.getRefundstatus())
                .note(order.getNote())
                .payTime(order.getPaytime().getTime())
                .refundTime(order.getRefundtime().getTime())
                .itemCount(order.getTotalquantity())
                .orderItems(orderItems)
                .payCard(payCard)
                .productOrderUrl(order.getProductOrderUrl())
                .SMKAccountBalance(null)
                .build();



    }

    public List<OrderVO> toOrderVOsNew(List<BinguoOrder> orders, Map<Integer, String> shopNameMap){
        if(orders.isEmpty()){
            return new ArrayList<>();
        }
        List<String> orderNos = orders.stream().map(BinguoOrder::getOrderno).collect(Collectors.toList());
        Map<String, List<OrderItem>> orderItemMap = _getOrderItemMap(orderNos);


        return toBuildOrderVO(orders, orderItemMap, shopNameMap);
    }

    public List<OrderVO> toOrderVOs(List<BinguoOrder> orders){
        if(orders.isEmpty()){
            return new ArrayList<>();
        }
        List<String> orderNos = orders.stream().map(BinguoOrder::getOrderno).collect(Collectors.toList());
        List<Integer> shopIds = orders.stream().map(BinguoOrder::getShopid).collect(Collectors.toList());
        Map<String, List<OrderItem>> orderItemMap = _getOrderItemMap(orderNos);
        Map<Integer, String> shopNameMap = _getShopNameMap(shopIds);
        return toBuildOrderVO(orders, orderItemMap, shopNameMap);
    }

    public List<OrderVOInWX> toOrderVOInWX(List<BinguoOrder> orders){
        if(orders.isEmpty()){
            return new ArrayList<>();
        }
        List<Integer> shopIds = orders.stream().map(BinguoOrder::getShopid).collect(Collectors.toList());
        List<Integer> groupIds = orders.stream().map(BinguoOrder::getCustomergroupid).collect(Collectors.toList());
        List<String> orderNos = orders.stream().map(BinguoOrder::getOrderno).collect(Collectors.toList());
        Map<String, List<OrderItem>> orderItemMap = _getOrderItemMap(orderNos);
        Map<Integer, String> shopNameMap = _getShopNameMap(shopIds);
        Map<Integer, String> groupNameMap = _getGroupNameMap(groupIds);
        return toBuildOrderVONew(orders, orderItemMap, shopNameMap,groupNameMap);
    }


    public List<OrderItemVO> getOrderItemListByOrderNo(String orderNo) {
        Condition condition = new Condition(OrderItem.class);
        condition.or().andEqualTo("orderno", orderNo);
        return orderItemRepository.findByCondition(condition).stream().map(item ->
                OrderItemVO.builder()
                        .productId(item.getProductid())
                        .productName(item.getProductname())
                        .price(item.getPrice())
                        .realPrice(item.getRealprice())
                        .calorie(item.getCalorie())
                        .quantity(item.getQuantity()).build()
        ).collect(Collectors.toList());
    }


    private Map<String, List<OrderItem>> _getOrderItemMap(List<String> orderNos){
        Condition condition = new Condition(OrderItem.class);
        condition.or().andIn("orderno", orderNos);
        return orderItemRepository.findByCondition(condition).stream().collect(Collectors.groupingBy(OrderItem::getOrderno));
    }



    private Map<Integer, String> _getShopNameMap(List<Integer> shopIds){
        return shopService.findByIds(shopIds).stream().collect(Collectors.toMap(Shop::getId, Shop::getName));
    }

    private Map<Integer, String> _getGroupNameMap(List<Integer> groupIds){
        return shopService.findGroupByIds(groupIds).stream().collect(Collectors.toMap(CustomerGroup::getId, CustomerGroup::getGroupName));
    }

    private List<OrderVO> toBuildOrderVO(List<BinguoOrder> orders, Map<String, List<OrderItem>> orderItemMap, Map<Integer, String> shopNameMap ){
        if(orders.isEmpty()) {
            return null;
        }
        return orders.stream().map(order ->
                OrderVO.builder()
                        .id(order.getId())
                        .orderNo(order.getOrderno())
                        .serialNumber(order.getSerialnumber())
                        .shopId(order.getShopid())
                        .shopName(shopNameMap.getOrDefault(order.getShopid(), ""))
                        .cashierDeskId(order.getCashierdeskid())
                        .customerId(order.getCustomerid())
                        .customerName(order.getCustomername())
                        .customerPhone(order.getCustomerphone())
                        .payType(order.getSource())
                        .totalFee(order.getTotalfee())
                        .realFee(order.getRealfee())
                        .refundFee(order.getRefundfee())
                        .payStatus(order.getPaystatus())
                        .refundStatus(order.getRefundstatus())
                        .note(order.getNote())
                        .payTime(order.getPaytime().getTime())
                        .itemCount(order.getTotalquantity())
                        .orderItems(orderItemMap.get(order.getOrderno()).stream().map(item ->
                                OrderItemVO.builder()
                                        .productId(item.getProductid())
                                        .productName(item.getProductname())
                                        .price(item.getPrice())
                                        .realPrice(item.getRealprice())
                                        .hasInfo(false)
                                        .quantity(item.getQuantity()).build()

                        ).collect(Collectors.toList())).build()
        ).collect(Collectors.toList());
    }



    private List<OrderVOInWX> toBuildOrderVONew(List<BinguoOrder> orders, Map<String, List<OrderItem>> orderItemMap, Map<Integer, String> shopNameMap,Map<Integer,String> groupNameMap){
        if(orders.isEmpty()) {
            return null;
        }

        return orders.stream().map(order ->
                OrderVOInWX.builder()
                        .orderNo(order.getOrderno())
                        .serial(order.getSerial())
                        .serialNumber(order.getSerialnumber())
                        .shopId(order.getShopid())
                        .shopName(shopNameMap.getOrDefault(order.getShopid(), ""))
                        .cashierDeskId(order.getCashierdeskid())
                        .customerId(order.getCustomerid())
                        .customerName(null ==order.getCustomername()?"":order.getCustomername())
                        .customerPhone(order.getCustomerphone())
                        .customerGroupName(null == order.getCustomergroupid()?"":groupNameMap.getOrDefault(order.getCustomergroupid(),""))
                        .payType(order.getSource())
                        .totalFee(order.getTotalfee())
                        .realFee(order.getRealfee())
                        .orderType(order.getOrdertype())
                        .refundFee(order.getRefundfee())
                        .payStatus(order.getPaystatus())
                        .refundStatus(order.getRefundstatus())
                        .note(order.getNote())
                        .payTime(order.getPaytime().getTime())
                        .createTime(order.getCreated().getTime())
                        .itemCount(order.getTotalquantity())
                        .orderItems(orderItemMap.get(order.getOrderno()).stream().map(item ->
                                OrderItemVO.builder()
                                        .productId(item.getProductid())
                                        .productName(item.getProductname())
                                        .price(item.getPrice())
                                        .realPrice(item.getRealprice())
                                        .hasInfo(false)
                                        .quantity(item.getQuantity()).build()
                        ).collect(Collectors.toList())).build()
        ).collect(Collectors.toList());
    }


}
